#include <inc/types.h>

#include <kern/sleeplock.h>
#include <kern/proc.h>


// sleeplock 实现参考了 xv6-public

void
sleep_initlock(struct sleeplock *lk)
{
	spin_initlock(&lk->lock);
	lk->locked = 0;
}

void
sleep_lock(struct sleeplock *lk)
{
	spin_lock(&(lk->lock));
	while (lk->locked)
		sleep((void *)lk, &lk->lock);

	lk->locked = 1;
	lk->pid = thisproc()->pid;
	spin_unlock(&lk->lock);
}

void
sleep_unlock(struct sleeplock *lk)
{
	spin_lock(&(lk->lock));
	lk->locked = 0;
	lk->pid = 0;
	wakeup((void *)lk);
	spin_unlock(&lk->lock);
}

// Whether current process is holding the sleeplock
int
sleep_holding(struct sleeplock *lk)
{
	bool ret;
	spin_lock(&(lk->lock));
	ret = lk->locked && (lk->pid == thisproc()->pid);
	spin_unlock(&(lk->lock));
	return ret;
}
